package com.enation.app.javashop.core.distribution.service.impl;

import com.enation.app.javashop.core.base.model.enums.YesNoEnum;
import com.enation.app.javashop.core.distribution.model.dos.DistributionMissionDetailDO;
import com.enation.app.javashop.core.distribution.model.dos.DistributionMissionRewardDO;
import com.enation.app.javashop.core.distribution.model.dos.DistributionMissionScheduleDO;
import com.enation.app.javashop.core.distribution.model.dto.CompleteRewardResult;
import com.enation.app.javashop.core.distribution.model.vo.DistributionMissionScheduleVO;
import com.enation.app.javashop.core.distribution.model.vo.DistributionMissionVO;
import com.enation.app.javashop.core.distribution.model.vo.QueryDistributionMissionScheduleVO;
import com.enation.app.javashop.core.distribution.service.DistributionMissionRewardManager;
import com.enation.app.javashop.core.distribution.service.DistributionMissionScheduleService;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.promotion.coupon.service.CouponManager;
import com.enation.app.javashop.core.trade.order.model.dos.OrderDO;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.util.SqlSplicingUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 孙建
 * 团长任务service实现
 */
@Service
public class DistributionMissionScheduleServiceImpl implements DistributionMissionScheduleService {

    @Autowired
    @Qualifier("distributionDaoSupport")
    private DaoSupport daoSupport;
    @Autowired
    private MemberManager memberManager;
    @Autowired
    private CouponManager couponManager;
    @Autowired
    private DistributionMissionRewardManager distributionMissionRewardManager;

    /**
     * 创建团长任务进度
     */
    @Override
    public DistributionMissionScheduleDO createMissionSchedule(Member member, DistributionMissionVO distributionMission, DistributionMissionDetailDO distributionMissionDetailDO, String missionTime) {
        DistributionMissionScheduleDO missionScheduleDO = new DistributionMissionScheduleDO();
        missionScheduleDO.setMissionId(distributionMission.getId());
        missionScheduleDO.setMissionDetailId(distributionMissionDetailDO.getId());
        missionScheduleDO.setMissionName(distributionMission.getMissionName());
        missionScheduleDO.setMissionType(distributionMissionDetailDO.getMissionType());
        missionScheduleDO.setMissionTarget(distributionMissionDetailDO.getMissionTarget());
        missionScheduleDO.setMissionTime(missionTime);
        missionScheduleDO.setTotalReward(BigDecimal.ZERO);
        missionScheduleDO.setTargetValue(getMaxTarget(distributionMissionDetailDO));
        missionScheduleDO.setCompleteValue(BigDecimal.ZERO);
        missionScheduleDO.setMemberId(member.getMemberId());
        missionScheduleDO.setMemberName(member.getRealName());
        missionScheduleDO.setSellerId(distributionMission.getSellerId());
        missionScheduleDO.setSellerName(distributionMission.getSellerName());
        missionScheduleDO.setIsDelete(0);
        daoSupport.insert(missionScheduleDO);
        return missionScheduleDO;
    }

    @Override
    public void updateMissionSchedule(DistributionMissionScheduleDO distributionMissionScheduleDO) {
        daoSupport.update(distributionMissionScheduleDO, distributionMissionScheduleDO.getId());
    }

    @Override
    public DistributionMissionScheduleDO queryDistributionMissionSchedule(Integer memberId, Integer missionId, Integer missionDetailId, Integer missionType, String missionTime) {
        return daoSupport.queryForObject("select * from es_distribution_mission_schedule where member_id = ? and mission_id = ? and mission_detail_id = ? and mission_type = ? and mission_time = ? and is_delete = 0",
                DistributionMissionScheduleDO.class, memberId, missionId, missionDetailId, missionType, missionTime);
    }


    /**
     * 根据条件查询任务进度
     */
    @Override
    public Page<DistributionMissionScheduleVO> queryMissionScheduleList(QueryDistributionMissionScheduleVO queryDistributionMissionScheduleVO) {
        // 1.组装查询条件参数
        StringBuilder sql = new StringBuilder("select dms.*,m.mobile from es_distribution_mission_schedule dms left join es_member m on dms.member_id=m.member_id");

        List<Object> termList = new ArrayList<>();
        List<String> sqlSplit = new ArrayList<>();

        Integer sellerId = queryDistributionMissionScheduleVO.getSellerId();
        if (sellerId != null) {
            sqlSplit.add(" dms.seller_id=? ");
            termList.add(sellerId);
        }

        sqlSplit.add(" dms.is_delete=? ");
        termList.add(YesNoEnum.NO.getIndex());

        // 团长名称查询
        String leaderName = queryDistributionMissionScheduleVO.getLeaderName();
        if (StringUtil.notEmpty(leaderName)) {
            sqlSplit.add(" dms.leader_name=? ");
            termList.add("%" + leaderName + "%");
        }

        // 任务明细类型查询
        Integer missionType = queryDistributionMissionScheduleVO.getMissionType();
        if (!ObjectUtils.isEmpty(missionType)) {
            sqlSplit.add(" dms.mission_type=? ");
            termList.add(missionType);
        }

        // 任务明细指标查询
        Integer missionTarget = queryDistributionMissionScheduleVO.getMissionTarget();
        if (!ObjectUtils.isEmpty(missionTarget)) {
            sqlSplit.add(" dms.mission_target=? ");
            termList.add(missionTarget);
        }

        // 2.对sql条件语句进行拼接并查询
        String sqlSplicing = SqlSplicingUtil.sqlSplicing(sqlSplit);
        if (StringUtil.notEmpty(sqlSplicing)) {
            sql.append(sqlSplicing);
        }
        sql.append(" order by dms.create_time desc");
        return this.daoSupport.queryForPage(sql.toString(), queryDistributionMissionScheduleVO.getPageNo(), queryDistributionMissionScheduleVO.getPageSize(),
                DistributionMissionScheduleVO.class, termList.toArray());
    }

    @Override
    public void deleteDistributionMissionScheduleByMissionId(Integer missionId) {
        String sql = "update es_distribution_mission_schedule set is_delete=1 where mission_id=? and is_delete=0";
        daoSupport.execute(sql, missionId);
    }

    /**
     * 进度增长
     */
    @Override
    public void increase(DistributionMissionVO distributionMission, DistributionMissionDetailDO distributionMissionDetailDO, DistributionMissionScheduleDO missionScheduleDO, OrderDO orderDO) {
        Integer missionTarget = distributionMissionDetailDO.getMissionTarget();
        BigDecimal increaseValue = null;
        // 累计人数
        if (missionTarget == 0) {
            increaseValue = BigDecimal.valueOf(1);
        } else {
            increaseValue = BigDecimal.valueOf(orderDO.getOrderPrice());
        }

        // 判断是否完成某个阶段 如果完成就需要累计奖金和发放奖励
        CompleteRewardResult completeRewardResult = getCompleteReward(missionScheduleDO.getCompleteValue().add(increaseValue), distributionMission, distributionMissionDetailDO, missionScheduleDO);
        if (completeRewardResult.isSuccess()) {
            // 更新任务完成阶段
            updateMissionSchedule(missionScheduleDO);

            // 更新进度完成值和总奖励金额
            BigDecimal levelReward = completeRewardResult.getLevelReward();
            daoSupport.execute("update es_distribution_mission_schedule set complete_value = complete_value + "
                    + increaseValue + ", total_reward = total_reward + " + levelReward + " where id = " + missionScheduleDO.getId());

            // 根据奖励类型发放奖励
            Integer rewardsType = distributionMission.getRewardsType();
            if (rewardsType == 1) {
                // 保存奖励明细
                DistributionMissionRewardDO missionRewardDO = new DistributionMissionRewardDO();
                missionRewardDO.setRewardsType(distributionMission.getRewardsType());
                missionRewardDO.setMissionId(distributionMissionDetailDO.getMissionId());
                missionRewardDO.setMissionDetailId(distributionMissionDetailDO.getId());
                missionRewardDO.setMissionScheduleId(missionScheduleDO.getId());
                missionRewardDO.setMissionType(missionScheduleDO.getMissionType());
                missionRewardDO.setMissionTime(missionScheduleDO.getMissionTime());
                missionRewardDO.setMemberId(missionScheduleDO.getMemberId());
                missionRewardDO.setMemberName(missionScheduleDO.getMemberName());
                missionRewardDO.setSellerId(missionScheduleDO.getSellerId());
                missionRewardDO.setSellerName(missionScheduleDO.getSellerName());
                missionRewardDO.setRewardMoney(levelReward);
                missionRewardDO.setRewardStatus(1);
                distributionMissionRewardManager.createDisMisReward(missionRewardDO);

                // 发放优惠券
                Member member = memberManager.getMemberById(missionScheduleDO.getMemberId());
                couponManager.issueVouchersToUsers(member, completeRewardResult.getLevelCouponId());
            } else {
                // 暂时没有红包奖励
            }
        } else {
            // 仅仅增加进度
            daoSupport.execute("update es_distribution_mission_schedule set complete_value = complete_value + " + increaseValue + " where id = " + missionScheduleDO.getId());
        }
    }

    /**
     * 进度减少
     */
    @Override
    public void decrease(DistributionMissionVO distributionMission, DistributionMissionDetailDO distributionMissionDetailDO, DistributionMissionScheduleDO missionScheduleDO, OrderDO orderDO) {
        Integer missionTarget = distributionMissionDetailDO.getMissionTarget();
        BigDecimal increaseValue = null;
        // 累计人数
        if (missionTarget == 0) {
            increaseValue = BigDecimal.valueOf(1);
        } else {
            increaseValue = BigDecimal.valueOf(orderDO.getOrderPrice());
        }
        daoSupport.execute("update es_distribution_mission_schedule set complete_value = complete_value - " + increaseValue + " where id = " + missionScheduleDO.getId());
    }


    /**
     * 获取任务最大目标值
     */
    private BigDecimal getMaxTarget(DistributionMissionDetailDO distributionMissionDetailDO) {
        Integer level4Target = distributionMissionDetailDO.getLevel4Target();
        if (level4Target != null && level4Target > 0) {
            return BigDecimal.valueOf(level4Target);
        }
        Integer level3Target = distributionMissionDetailDO.getLevel3Target();
        if (level3Target != null && level3Target > 0) {
            return BigDecimal.valueOf(level3Target);
        }
        Integer level2Target = distributionMissionDetailDO.getLevel2Target();
        if (level2Target != null && level2Target > 0) {
            return BigDecimal.valueOf(level2Target);
        }
        Integer level1Target = distributionMissionDetailDO.getLevel1Target();
        if (level1Target != null && level1Target > 0) {
            return BigDecimal.valueOf(level1Target);
        }
        return BigDecimal.ZERO;
    }


    /**
     * 获取完成阶段的奖励金额
     */
    private CompleteRewardResult getCompleteReward(BigDecimal currentCompleteValue, DistributionMissionVO distributionMission, DistributionMissionDetailDO distributionMissionDetailDO, DistributionMissionScheduleDO missionScheduleDO) {

        // 当前已经得到的奖励
        BigDecimal totalReward = missionScheduleDO.getTotalReward();
        // 这次要给的奖励
        BigDecimal reward = new BigDecimal(0);
        // 任务奖励类型
        Integer rewardsType = distributionMission.getRewardsType();

        BigDecimal level1Reward = null;
        BigDecimal level2Reward = null;
        BigDecimal level3Reward = null;
        BigDecimal level4Reward = null;
        if (rewardsType == 0) {
            level1Reward = distributionMissionDetailDO.getLevel1Cash() != null ? distributionMissionDetailDO.getLevel1Cash() : BigDecimal.ZERO;
            level2Reward = distributionMissionDetailDO.getLevel2Cash() != null ? distributionMissionDetailDO.getLevel2Cash() : BigDecimal.ZERO;
            level3Reward = distributionMissionDetailDO.getLevel3Cash() != null ? distributionMissionDetailDO.getLevel3Cash() : BigDecimal.ZERO;
            level4Reward = distributionMissionDetailDO.getLevel4Cash() != null ? distributionMissionDetailDO.getLevel4Cash() : BigDecimal.ZERO;
        } else {
            // 优惠券查询比较麻烦 前端直接把优惠券金额保存到levelxCash字段中即可
            level1Reward = distributionMissionDetailDO.getLevel1Cash() != null ? distributionMissionDetailDO.getLevel1Cash() : BigDecimal.ZERO;
            level2Reward = distributionMissionDetailDO.getLevel2Cash() != null ? distributionMissionDetailDO.getLevel2Cash() : BigDecimal.ZERO;
            level3Reward = distributionMissionDetailDO.getLevel3Cash() != null ? distributionMissionDetailDO.getLevel3Cash() : BigDecimal.ZERO;
            level4Reward = distributionMissionDetailDO.getLevel4Cash() != null ? distributionMissionDetailDO.getLevel4Cash() : BigDecimal.ZERO;
        }

        // 刚好相等说明已经第四阶段完成目标
        Integer level4Target = distributionMissionDetailDO.getLevel4Target();
        if (level4Target != null && currentCompleteValue.compareTo(BigDecimal.valueOf(level4Target)) >= 0) {
            // 如果是有人故意在临界点反复下单退单 需要忽略此场景
            if (totalReward.compareTo(level1Reward.add(level2Reward).add(level3Reward).add(level4Reward)) > 0) {
                // 说明已经领过了 忽略
                return new CompleteRewardResult(false);
            }

            missionScheduleDO.setLevel4Status(1);
            if (missionScheduleDO.getLevel1Status() == 0 && missionScheduleDO.getLevel2Status() == 0 && missionScheduleDO.getLevel3Status() == 0) {
                // 说明没有领过1/2/3级奖励
                reward = reward.add(level4Reward);
            } else {
                return new CompleteRewardResult(true, level4Reward, distributionMissionDetailDO.getLevel4CouponId());
            }
        }

        // 刚好相等说明已经第三阶段完成目标
        Integer level3Target = distributionMissionDetailDO.getLevel3Target();
        if (level3Target != null && currentCompleteValue.compareTo(BigDecimal.valueOf(level3Target)) >= 0) {
            // 如果是有人故意在临界点反复下单退单 需要忽略此场景
            if (totalReward.compareTo(level1Reward.add(level2Reward).add(level3Reward)) > 0) {
                // 说明已经领过了 忽略
                return new CompleteRewardResult(false);
            }

            missionScheduleDO.setLevel3Status(1);
            if (missionScheduleDO.getLevel1Status() == 0 && missionScheduleDO.getLevel2Status() == 0) {
                // 说明没有领过1/2级奖励
                reward = reward.add(level3Reward);
            } else {
                // 如果奖励金额>0，说明需要同时给几个阶段的奖励，所以要相加
                if (reward.compareTo(new BigDecimal(0)) == 1) {
                    level3Reward = reward.add(level3Reward);
                }
                return new CompleteRewardResult(true, level3Reward, distributionMissionDetailDO.getLevel3CouponId());
            }
        }

        // 刚好相等说明已经第二阶段完成目标
        Integer level2Target = distributionMissionDetailDO.getLevel2Target();
        if (level2Target != null && currentCompleteValue.compareTo(BigDecimal.valueOf(level2Target)) >= 0) {
            // 如果是有人故意在临界点反复下单退单 需要忽略此场景
            if (totalReward.compareTo(level1Reward.add(level2Reward)) > 0) {
                // 说明已经领过了 忽略
                return new CompleteRewardResult(false);
            }

            missionScheduleDO.setLevel2Status(1);
            if (missionScheduleDO.getLevel1Status() == 0) {
                // 说明没有领过1级奖励
                reward = reward.add(level2Reward);
            } else {
                // 如果奖励金额>0，说明需要同时给几个阶段的奖励，所以要相加
                if (reward.compareTo(new BigDecimal(0)) == 1) {
                    level2Reward = reward.add(level2Reward);
                }
                return new CompleteRewardResult(true, level2Reward, distributionMissionDetailDO.getLevel2CouponId());
            }

        }

        // 刚好相等说明已经第一阶段完成目标
        Integer level1Target = distributionMissionDetailDO.getLevel1Target();
        if (level1Target != null && currentCompleteValue.compareTo(BigDecimal.valueOf(level1Target)) >= 0) {
            // 如果是有人故意在临界点反复下单退单 需要忽略此场景
            if (totalReward.compareTo(level1Reward) > 0) {
                // 说明已经领过了 忽略
                return new CompleteRewardResult(false);
            }
            missionScheduleDO.setLevel1Status(1);
            // 如果奖励金额>0，说明需要同时给几个阶段的奖励，所以要相加
            if (reward.compareTo(new BigDecimal(0)) == 1) {
                level1Reward = reward.add(level1Reward);
            }
            return new CompleteRewardResult(true, level1Reward, distributionMissionDetailDO.getLevel1CouponId());
        }
        return new CompleteRewardResult(false);
    }
}
